#pragma once

namespace Tmpl {

typedef std::deque<MsgData> MsgArray;

class Image;
class Entity
{
public:
	enum EntityStatus
	{
		ENTSTATUS_ALIVE,
		ENTSTATUS_REMOVE,
		ENTSTATUS_REMOVED
	};

	enum EntityFlags
	{
		ENTITY_NONE					= 0,
		ENTITY_UNIT					= 1 << 0,
		ENTITY_HERO					= 1 << 1,
		ENTITY_BUILDING				= 1 << 2,
		ENTITY_TREE					= 1 << 3,
		ENTITY_DOODADD				= 1 << 4,
		ENTITY_PROJECTILE			= 1 << 5,
		ENTITY_ALL					= 0xFFFFFFFF
	};

	// Base Functions
	void Init(int id, int ownerId, int empireId, Vec2f pos, Vec2f facing, const UnitData& data);
	void Remove();
	void Kill();

	int GetId() const { return mId; }
	int GetOwnerId() const { return mOwnerId; }
	int GetEmpire() const { return mEmpire; }
	void IncDeathTimer() { ++mDeathTimer; }

	// Render
	void RenderLogic() const;

	// Status
	void SetStatus(int status){ mStatus = status; }
	int GetStatus() const { return mStatus; }

	bool IsAlive() const {return mStatus == ENTSTATUS_ALIVE;}
	bool IsRemoved() const {return mStatus == ENTSTATUS_REMOVE || mStatus == ENTSTATUS_REMOVED;}
	bool AllowRemove() const {return mStatus == ENTSTATUS_REMOVE && mDeathTimer > 30; }

	void SetTarget(int target);

	// Flags
	void SetFlags(int flag){mFlags = flag; }
	void AddFlag(int flag){mFlags |= flag; }
	void RemoveFlag(int flag){mFlags &= ~flag; }
	bool HasFlag(int flag) const {return ((mFlags & flag) == flag);}
	int GetFlags() const {return mFlags; }

	bool IsUnit() const {return HasFlag(ENTITY_UNIT);}
	bool IsHero() const {return HasFlag(ENTITY_HERO);}
	bool IsBuilding() const {return HasFlag(ENTITY_BUILDING);}
	bool IsProjectile() const {return HasFlag(ENTITY_PROJECTILE);}
	bool IsTree() const {return HasFlag(ENTITY_TREE);}
	bool IsDoodadd() const {return HasFlag(ENTITY_DOODADD) || HasFlag(ENTITY_TREE);}

	// Stats
	float GetHPPercent() const;
	float GetHPMax() const;
	float GetHP() const;

	// Movement
	Vec2f GetPos() const;
	Vec2f GetFacing() const;
	float GetSize() const;
	float GetSpeed() const;
	float GetMaxSpeed() const;

	Vec2f GetNextPos() const;
	Vec2f GetNextFacing() const;
	float GetNextSize() const;
	float GetNextSpeed() const;

	void SetPos(Vec2f pos);
	void SetFacing(Vec2f facing);
	void SetSize(float size);
	void SetSpeed(float speed);

	// Messaging
	MsgData* AddNewMessage();
	void HandleAllMessages();
	void HandleMessage(const MsgData& msg);

protected:
	int mId;
	int mOwnerId;
	int mEmpire;

	int mStatus;
	int mFlags;

	char mDeathTimer;

	// Modules
	int mStats;
	int mMovement;
	int mLogic;

	// Messages
	MsgArray mMessages;
};

}; // namespace Tmpl